import java.net.*;
import java.io.*;
import java.util.Arrays;

public class Robot extends Thread{
	private int port;
	private String host;
	private String name;
	private Socket socket;
	private Connection conn;
	
	Player player;
	Table table;
	int second;//打牌速度，等待几秒
	public Robot(){
		this(1);
	}
	public Robot(int second){
		port = 5656;
		host = "localhost";
		name = "Computer";
		socket = null;
		conn = null;
		this.second = second;
		try{
			socket=new Socket(InetAddress.getByName(host),port);
		}catch(IOException ex){ ex.printStackTrace();}
		conn=new Connection(socket);
		player=new Player();
		player.autoPlay=true;
		if(name==null){
			player.name=System.getProperty("user.name");
		}
		else player.name=name;
		player.setConn(conn);
		table=new Table();
	}


	public void run(){

		while (true){

			perform(conn.receiveMsg());
			try{
				sleep(second*1000);
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		}	
		
		
	private void auction(String str){
		int seat=Connection.getIntValue("seat",str);
		table.bid=Connection.getIntValue("bid",str);
		int bid=0;
		table.setGameState(Table.AUCTION);
		if(player.seatNum==seat&&player.state== Player.READY){
			int [] cards=player.getCards();
			if(cards[15]>=48) bid=3;
			String txt="cmd="+Connection.CMD_AUCTION
        			+"&ID="+player.id
        			+"&seat="+player.seatNum
        			+"&bid="+bid;
        		player.conn.sendMsg(txt);
        		player.setState(Player.WAIT_OTHER);
		}
	}	
		
	public 	void perform(String str){
		int cmd=Connection.CMD_ILLEGAL;
		String type;
		String playerID;
		int [] cardsValue;
		
		cmd=conn.getCmd(str);
		switch(cmd){
		case Connection.CMD_SETID: setID(str);break;
		case Connection.CMD_JOIN: playerJoin(str);break;
		case Connection.CMD_READY: playerReady(str);break;
		case Connection.CMD_TABLEINFO: tableInfo(str);break;
		case Connection.CMD_DEALCARDS: dealCards(str);break;
		case Connection.CMD_AUCTION: auction(str);break;
		case Connection.CMD_SETLANDLORD: setLandlord(str);break;
		case Connection.CMD_PLAY: play(str);break;
		case Connection.CMD_WIN: win(str);break;
		}
	}
	
	private void dealCards(String str){
		int [] cardsValue;
		cardsValue=conn.getCards(str);
		java.util.Arrays.sort(cardsValue);
		player.receiveCards(cardsValue);
		int cards[]=new int[17];
		Arrays.fill(cards,55);
		table.players[(player.seatNum+1)%3].receiveCards(cards);
		cards=new int[17];
		Arrays.fill(cards,55);
		table.players[(player.seatNum+2)%3].receiveCards(cards);
		table.lastCards=new int[3];
		Arrays.fill(table.lastCards,55);
	}	
		
	
	private void setLandlord(String str){
		int id=Connection.getIntValue("ID",str);
		table.landlord=id;
		table.currentPlayer=Connection.getIntValue("seat",str);
		table.bid=Connection.getIntValue("bid",str);
		table.scoreMultiple=1;
		
		int[] cards=Connection.getCards(str);
		table.setLastCards(cards);
		table.setGameState(Table.NEWLOOP);
		if(player.id==id) {
			Debug.println("Robot,setLandLord,105");
			player.receiveCards(cards);
			player.setState(Player.THINKING);
			autoPlay();
		}
		else{
			int []newCards=new int[3];
			java.util.Arrays.fill(newCards,55);
			int seatNum=Connection.getIntValue("seat",str);
			table.players[seatNum].receiveCards(newCards);
		}
		table.setGameState(Table.NEWLOOP);
	}
		
	public void play(String str){
		int [] cards=Connection.getCards(str);
		int seatNum=Connection.getIntValue("seat",str);
		if(cards[0]==0) {//player pass
			table.players[seatNum].setDisCards(cards);
			table.passTime++;
			}
		else if(player.seatNum==seatNum){
			player.removeCards(cards);
			player.setDisCards(cards);
			int [] newCards=new int[cards.length];
			System.arraycopy(cards,0,newCards,0,cards.length);
			table.bigCards=newCards;
			table.passTime=0;
		}
		else{
			int [] newCards=new int[cards.length];
			java.util.Arrays.fill(newCards,55);
			table.players[seatNum].removeCards(newCards);
			table.players[seatNum].setDisCards(cards);
			newCards=new int[cards.length];
			System.arraycopy(cards,0,newCards,0,cards.length);
			table.bigCards=newCards;
			table.passTime=0;
			}
		table.players[table.currentPlayer].setState(Player.WAIT_OTHER);
		table.currentPlayer=(table.currentPlayer+1)%3;
		if(table.gameState==Table.NEWLOOP) table.setGameState(Table.PLAY);
		if(table.passTime==2){
			table.curLoop++;
			table.passTime=0;
			for(int i=0;i<3;i++) table.players[i].clearDisCards();
			table.setGameState(Table.NEWLOOP);
		}
		
		for(int i=0;i<3;i++){
			if(table.players[i].cardNum()==0) {
				win(i);
				return;
			}
		}
		table.players[table.currentPlayer].setState(Player.THINKING);
		if(player.autoPlay) autoPlay();
	}	
	
	  void ready(){
		String msg="cmd="+Connection.CMD_READY
					+"&seat="+player.seatNum
					+"&ID="+player.id;
		player.conn.sendMsg(msg);
		
		}	
			
    	
    public void joinGame(String host,int port){
    	Thread t=new Thread(this);
    	t.start();
    	}
    private void joinTable(){
    	String msg;
    	msg="cmd="+Connection.CMD_JOIN+"&ID="+player.id;
    	player.conn.sendMsg(msg);
    }
    private void sendPlayerInfo(){
    	String msg;
    	msg="cmd="+Connection.CMD_USERINFO
    		+"&ID="+player.id
    		+"&name="+player.name
    		+"&score="+player.score;
    	player.conn.sendMsg(msg);
    	}	
    private void setID(String str){
    	player.setID(Connection.getValue("ID",str));
    	sendPlayerInfo();
    	joinTable();
    }
    	
	private void playerJoin(String str){
		int id=Integer.parseInt(Connection.getValue("id",str));
		String name=Connection.getValue("name",str);
		int score=Integer.parseInt(Connection.getValue("score",str));
		int seat=Integer.parseInt(Connection.getValue("seat",str));
		if(id==player.id){
			player.seatNum=seat;
			table.addPlayer(player,seat);
			try {
				sleep(100);
				}
				catch (Exception ex) {}
			
			ready();
			} 
		else {
			Player m=new Player();
			m.id=id;
			m.name=name;
			m.score=score;
			m.seatNum=seat;
			table.addPlayer(m,seat);
		}		
	}
	
	
	private void playerReady(String str){
		int seat,id;
		seat=Connection.getIntValue("seat",str);
		id=Connection.getIntValue("id",str);
		table.players[seat].setState(Player.READY);
	}
	
	private void tableInfo(String str){
		int playerNum=Connection.getIntValue("playerNum",str);
		int seat,id,seatNum,score,state;
		String name;
		for(int i=0;i<3;i++){
			seat=Connection.getIntValue("seat"+i,str);
			if(seat==1){
				id=Connection.getIntValue("id"+i,str);
				seatNum=Connection.getIntValue("seatNum"+i,str);
				score=Connection.getIntValue("score"+i,str);
				state=Connection.getIntValue("getGameState"+i,str);
				name=Connection.getValue("name"+i,str);
				Player m=new Player(id);
				m.setName(name);
				m.setScore(score);
				m.setState(state);
				table.addPlayer(m,seatNum);
			}
		}
	}
	
	private void win(String str){
		int seat=Connection.getIntValue("seat",str);
		if(seat==player.seatNum) player.score+=2*(table.bid)*table.scoreMultiple;
		else player.score=player.score-table.bid*table.scoreMultiple;
		newGame();
		ready();
	}
	
	private void win(int seat){
		for(int i=0;i<3;i++){
			if(seat==i) table.players[i].score+=2*(table.bid)*table.scoreMultiple;
			else table.players[i].score-=table.bid*table.scoreMultiple;
		}
		try{
			sleep(second*1000);
		}catch(Exception e){}
		newGame();
		ready();
	}
	
	public void newGame(){
		table.newGame();
	}
	
	
	public void autoPlay(){
		int [] newCards;
		try{sleep(1000);
		}catch(Exception e){
		}
		if((table.gameState==Table.PLAY||table.gameState==Table.NEWLOOP)&&player.state== Player.THINKING){
		if(table.gameState==Table.NEWLOOP&&table.currentPlayer==player.seatNum)
		{
			newCards=Rule.getSmallCards(player.getCards());
			playCards(newCards);
		}
		else{
			if(table.players[(player.seatNum+2)%3].id==table.landlord&&table.passTime==1){
				pass();
				return;
			}
			newCards=Rule.canPlay(player.getCards(),table.getBigCards());
			if(newCards==null) {pass();return;}
			playCards(newCards);
		}
		}
	}
	
		public void playCards(int [] cards){
		String msg;
		msg="cmd="+Connection.CMD_PLAY
			+"&ID="+player.id
			+"&seat="+player.seatNum
			+"&cards=";
		for(int i=0;i<cards.length;i++){
			msg+=cards[i]+",";
		}
		GameMessage gMsg = new GameMessage();
		gMsg.setCmd(GameMessage.CMD_PLAY);
		gMsg.addInfo("ID",player.id);
		gMsg.addInfo("seat",player.seatNum);
		gMsg.setCards(cards);
		//player.conn.sendMsg(msg);
		player.conn.sendMsg(gMsg.toString());
		player.setState(Player.WAIT_OTHER);
	}
	
	public void pass(){
		int [] newCards={0};
		playCards(newCards);
	}


	
	
}